package net.jgrm.redisadvanced.service;

import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * Redis Set类型操作服务接口
 */
public interface RedisSetService {

    /**
     * 向集合中添加一个或多个元素
     *
     * @param key    键
     * @param values 值
     * @return 添加成功的元素数量
     */
    Long add(String key, Object... values);

    /**
     * 获取集合中的所有元素
     *
     * @param key   键
     * @param clazz 返回值类型
     * @param <T>   返回值泛型
     * @return 元素集合
     */
    <T> Set<T> members(String key, Class<T> clazz);

    /**
     * 判断元素是否在集合中
     *
     * @param key   键
     * @param value 值
     * @return 是否存在
     */
    Boolean isMember(String key, Object value);

    /**
     * 获取集合的大小
     *
     * @param key 键
     * @return 集合大小
     */
    Long size(String key);

    /**
     * 从集合中移除一个或多个元素
     *
     * @param key    键
     * @param values 值
     * @return 移除成功的元素数量
     */
    Long remove(String key, Object... values);

    /**
     * 随机移除并返回集合中的一个元素
     *
     * @param key   键
     * @param clazz 返回值类型
     * @param <T>   返回值泛型
     * @return 移除的元素
     */
    <T> T pop(String key, Class<T> clazz);

    /**
     * 随机获取集合中的一个元素，但不移除
     *
     * @param key   键
     * @param clazz 返回值类型
     * @param <T>   返回值泛型
     * @return 随机元素
     */
    <T> T randomMember(String key, Class<T> clazz);

    /**
     * 随机获取集合中的多个元素，但不移除
     *
     * @param key   键
     * @param count 获取的元素数量
     * @param clazz 返回值类型
     * @param <T>   返回值泛型
     * @return 随机元素列表
     */
    <T> java.util.List<T> randomMembers(String key, long count, Class<T> clazz);

    /**
     * 获取两个集合的交集
     *
     * @param key1  第一个集合的键
     * @param key2  第二个集合的键
     * @param clazz 返回值类型
     * @param <T>   返回值泛型
     * @return 交集元素集合
     */
    <T> Set<T> intersect(String key1, String key2, Class<T> clazz);

    /**
     * 获取多个集合的交集
     *
     * @param key       目标集合的键
     * @param otherKeys 其他集合的键
     * @param clazz     返回值类型
     * @param <T>       返回值泛型
     * @return 交集元素集合
     */
    <T> Set<T> intersect(String key, String[] otherKeys, Class<T> clazz);

    /**
     * 将两个集合的交集存储到新的集合中
     *
     * @param key1    第一个集合的键
     * @param key2    第二个集合的键
     * @param destKey 目标集合的键
     * @return 交集元素的数量
     */
    Long intersectAndStore(String key1, String key2, String destKey);

    /**
     * 将多个集合的交集存储到新的集合中
     *
     * @param key       源集合的键
     * @param otherKeys 其他集合的键
     * @param destKey   目标集合的键
     * @return 交集元素的数量
     */
    Long intersectAndStore(String key, String[] otherKeys, String destKey);

    /**
     * 获取两个集合的并集
     *
     * @param key1  第一个集合的键
     * @param key2  第二个集合的键
     * @param clazz 返回值类型
     * @param <T>   返回值泛型
     * @return 并集元素集合
     */
    <T> Set<T> union(String key1, String key2, Class<T> clazz);

    /**
     * 获取多个集合的并集
     *
     * @param key       目标集合的键
     * @param otherKeys 其他集合的键
     * @param clazz     返回值类型
     * @param <T>       返回值泛型
     * @return 并集元素集合
     */
    <T> Set<T> union(String key, String[] otherKeys, Class<T> clazz);

    /**
     * 将两个集合的并集存储到新的集合中
     *
     * @param key1    第一个集合的键
     * @param key2    第二个集合的键
     * @param destKey 目标集合的键
     * @return 并集元素的数量
     */
    Long unionAndStore(String key1, String key2, String destKey);

    /**
     * 将多个集合的并集存储到新的集合中
     *
     * @param key       源集合的键
     * @param otherKeys 其他集合的键
     * @param destKey   目标集合的键
     * @return 并集元素的数量
     */
    Long unionAndStore(String key, String[] otherKeys, String destKey);

    /**
     * 获取两个集合的差集
     *
     * @param key1  第一个集合的键
     * @param key2  第二个集合的键
     * @param clazz 返回值类型
     * @param <T>   返回值泛型
     * @return 差集元素集合
     */
    <T> Set<T> difference(String key1, String key2, Class<T> clazz);

    /**
     * 获取多个集合的差集
     *
     * @param key       目标集合的键
     * @param otherKeys 其他集合的键
     * @param clazz     返回值类型
     * @param <T>       返回值泛型
     * @return 差集元素集合
     */
    <T> Set<T> difference(String key, String[] otherKeys, Class<T> clazz);

    /**
     * 将两个集合的差集存储到新的集合中
     *
     * @param key1    第一个集合的键
     * @param key2    第二个集合的键
     * @param destKey 目标集合的键
     * @return 差集元素的数量
     */
    Long differenceAndStore(String key1, String key2, String destKey);

    /**
     * 将多个集合的差集存储到新的集合中
     *
     * @param key       源集合的键
     * @param otherKeys 其他集合的键
     * @param destKey   目标集合的键
     * @return 差集元素的数量
     */
    Long differenceAndStore(String key, String[] otherKeys, String destKey);

    /**
     * 为集合设置过期时间
     *
     * @param key        键
     * @param expireTime 过期时间
     * @param timeUnit   时间单位
     * @return 设置是否成功
     */
    Boolean expire(String key, long expireTime, TimeUnit timeUnit);
}